//===============================================================================
// Microsoft patterns & practices Enterprise Library Contribution
// Resource Application Block
//===============================================================================

using System.Collections.Generic;
using System.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration.Manageability;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration.Manageability.Adm;
using EntLibContrib.Resource.Properties;

namespace EntLibContrib.Resource.Configuration.Manageability
{
	/// <summary>
	/// Provides an implementation for <see cref="DataResourceProviderData"/> that
	/// splits policy overrides processing and WMI objects generation, performing approriate logging of 
	/// policy processing errors.
	/// </summary>
	public class DataResourceProviderDataManageabilityProvider
		: ConfigurationElementManageabilityProviderBase<DataResourceProviderData>
	{
		#region Constants
		/// <summary>
		/// The name of the database instance name property.
		/// </summary>
		public const string DatabaseInstanceNamePropertyName = "databaseInstanceName";
		/// <summary>
		/// The name of the resource base name property.
		/// </summary>
		public const string ResourceBaseNamePropertyName = "resourceBaseName";
		#endregion

		#region Properties
		/// <summary>
		/// Gets the template for the name of the policy associated to the object.
		/// </summary>
		/// <value></value>
		/// <remarks>
		/// Elements that override
		/// <see cref="M:Microsoft.Practices.EnterpriseLibrary.Common.Configuration.Manageability.ConfigurationElementManageabilityProviderBase`1.AddAdministrativeTemplateDirectives(Microsoft.Practices.EnterpriseLibrary.Common.Configuration.Manageability.Adm.AdmContentBuilder,`0,Microsoft.Practices.EnterpriseLibrary.Common.Configuration.IConfigurationSource,System.String)"/>
		/// to avoid creating a policy must still override this property.
		/// </remarks>
		protected override string ElementPolicyNameTemplate
		{
			get
			{
				return null;	// no policy for these elements
			}
		}
		#endregion

		#region Construction
		/// <summary>
		/// Initializes a new instance of the <see cref="DataResourceProviderDataManageabilityProvider"/> class.
		/// </summary>
		/// <remarks>Default to ReadOnly</remarks>
		public DataResourceProviderDataManageabilityProvider()
    {
			DataResourceProviderDataWmiMapper.RegisterWmiTypes();
    }
		#endregion

		#region Protected Methods
		/// <summary>
		/// Adds the administrative template directives.
		/// </summary>
		/// <param name="contentBuilder">The content builder.</param>
		/// <param name="configurationObject">The configuration object.</param>
		/// <param name="configurationSource">The configuration source.</param>
		/// <param name="elementPolicyKeyName">Name of the element policy key.</param>
		protected override void AddAdministrativeTemplateDirectives(AdmContentBuilder contentBuilder,
																																DataResourceProviderData configurationObject,
																																IConfigurationSource configurationSource,
																																string elementPolicyKeyName)
		{
			// parts for providers are part of their resource manager's policies
			AddElementAdministrativeTemplateParts(contentBuilder,
																						configurationObject,
																						configurationSource,
																						elementPolicyKeyName);
		}

		/// <summary>
		/// Adds the element administrative template parts.
		/// </summary>
		/// <param name="contentBuilder">The content builder.</param>
		/// <param name="configurationObject">The configuration object.</param>
		/// <param name="configurationSource">The configuration source.</param>
		/// <param name="elementPolicyKeyName">Name of the element policy key.</param>
		protected override void AddElementAdministrativeTemplateParts(AdmContentBuilder contentBuilder, 
																																	DataResourceProviderData configurationObject, 
																																	IConfigurationSource configurationSource, 
																																	string elementPolicyKeyName)
		{
			List<AdmDropDownListItem> connectionStrings = new List<AdmDropDownListItem>();
			ConnectionStringsSection connectionStringsSection = (ConnectionStringsSection)configurationSource.GetSection("connectionStrings");
			if (connectionStringsSection != null)
			{
				foreach (ConnectionStringSettings connectionString in connectionStringsSection.ConnectionStrings)
				{
					connectionStrings.Add(new AdmDropDownListItem(connectionString.Name, connectionString.Name));
				}
			}
			contentBuilder.AddDropDownListPart(InternalResources.DataResourceProviderDataDatabaseInstanceNamePartName,
																				 elementPolicyKeyName,
																				 DatabaseInstanceNamePropertyName,
																				 connectionStrings,
																				 configurationObject.DatabaseInstanceName);

			contentBuilder.AddEditTextPart(InternalResources.DataResourceProviderDataResourceBaseNamePartName,
																		elementPolicyKeyName,
																		ResourceBaseNamePropertyName,
																		configurationObject.ResourceBaseName,
																		255,
																		true);
		}

		/// <summary>
		/// Creates the <see cref="T:Microsoft.Practices.EnterpriseLibrary.Common.Configuration.Manageability.ConfigurationSetting"/> instances that describe the
		/// configurationObject.
		/// </summary>
		/// <param name="configurationObject">The configuration object for instances that must be managed.</param>
		/// <param name="wmiSettings">A collection to where the generated WMI objects are to be added.</param>
		protected override void GenerateWmiObjects(DataResourceProviderData configurationObject, ICollection<ConfigurationSetting> wmiSettings)
		{
			DataResourceProviderDataWmiMapper.GenerateWmiObjects(configurationObject, wmiSettings);
		}

		/// <summary>
		/// Overrides the <paramref name="configurationObject"/>'s properties with the Group Policy values from the
		/// registry.
		/// </summary>
		/// <param name="configurationObject">The configuration object for instances that must be managed.</param>
		/// <param name="policyKey">The <see cref="T:Microsoft.Practices.EnterpriseLibrary.Common.Configuration.Manageability.IRegistryKey"/> which holds the Group Policy overrides for the
		/// configuration element.</param>
		/// <remarks>Subclasses implementing this method must retrieve all the override values from the registry
		/// before making modifications to the <paramref name="configurationObject"/> so any error retrieving
		/// the override values will cancel policy processing.</remarks>
		protected override void OverrideWithGroupPolicies(DataResourceProviderData configurationObject, IRegistryKey policyKey)
		{
			string databaseInstanceNameOverride = policyKey.GetStringValue(DatabaseInstanceNamePropertyName);
			string resourceBaseNameOverride = policyKey.GetStringValue(ResourceBaseNamePropertyName);

			configurationObject.DatabaseInstanceName = databaseInstanceNameOverride;
			configurationObject.ResourceBaseName = resourceBaseNameOverride;
		}
		#endregion
	}
}
